package com.rytong.tools.crypto;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

import com.rytong.tools.utils.Utils;

/**
 * 防篡改验证模块
 * 
 * @author Zhoucj
 * 
 */
public class AppVerify {
	/** 当前程序包名 */
	private static String packageName;
	/** 当前程序安装包路径 */
	private static String packageDir;

	static {
		try {
			System.loadLibrary("AppVerify");
		} catch (Throwable e) {
			Utils.printOutToConsole("Load libAppVerify failed");
		}
	}

	public static String getPackageName() {
		return packageName;
	}

	public static String getPackageDir() {
		return packageDir;
	}

	/**
	 * 分别使用native C++方法和java方法计算hash值，如果相同，则返回hash值；如果不同，则 返回null
	 * 
	 * @param key
	 *            校验用的key
	 * @param context
	 * 
	 * @return
	 */
	public static String verifyHash(byte[] key, Context context) {
		try {
			packageName = context.getPackageName();
			PackageManager pm = context.getPackageManager();
			ApplicationInfo pi = pm.getApplicationInfo(packageName,
					PackageManager.GET_UNINSTALLED_PACKAGES);
			if (pi != null) {
				packageDir = pi.sourceDir.substring(1, pi.sourceDir.length());
				Utils.printOutToConsole(packageDir);
			}

			byte[] sha1_C = verifyHashByC(key, key.length);
			if (sha1_C != null) {
				String hash_C = Base64.encode(sha1_C);
				if (hash_C != null) {
					Utils.printOutToConsole(hash_C);
					return hash_C;
				}
			}
		} catch (Throwable e) {
		}

		return null;
	}

	/**
	 * native C++方法，通过JNI调用so库实现
	 * 
	 * @param key
	 * @param keyLength
	 *            在java byte数组转为c++ char指针时，可能会出现数组中出现'\0'字符的情
	 *            况，导致key长度不确定，此处为保证正确性，将keyLength作为参数传递
	 * @param context
	 * @return
	 */
	private native static byte[] verifyHashByC(byte[] key, int keyLength);

}